<script setup>
import { ref, watch, onMounted, onBeforeUnmount, nextTick } from 'vue';
import { ElInput, ElButton, ElBadge, ElTag, ElScrollbar } from 'element-plus';

const props = defineProps({
  searchResults: {
    type: Object,
    default: () => ({ meridians: [], acupoints: [] })
  },
  showResults: {
    type: Boolean,
    default: false
  }
});

const emit = defineEmits(['search', 'clear', 'select']);

const searchQuery = ref('');
const searchTimeout = ref(null);
const searchInputRef = ref(null);
const searchResultsRef = ref(null);
const dropdownVisible = ref(false);
const activeIndex = ref(-1);
const recentSearches = ref([]);
const showRecentSearches = ref(false);
const isInputFocused = ref(false);

// Load recent searches from localStorage
const loadRecentSearches = () => {
  try {
    const saved = localStorage.getItem('meridian-recent-searches');
    if (saved) {
      recentSearches.value = JSON.parse(saved).slice(0, 5);
    }
  } catch (e) {
    console.error('Failed to load recent searches:', e);
  }
};

// Save recent searches to localStorage
const saveRecentSearches = () => {
  try {
    localStorage.setItem('meridian-recent-searches', JSON.stringify(recentSearches.value));
  } catch (e) {
    console.error('Failed to save recent searches:', e);
  }
};

// Emit search event with debounce
const onSearch = () => {
  clearTimeout(searchTimeout.value);
  
  if (searchQuery.value.trim() === '') {
    emit('clear');
    return;
  }
  
  searchTimeout.value = setTimeout(() => {
    emit('search', searchQuery.value);
    
    // Add to recent searches
    if (searchQuery.value.trim() && !recentSearches.value.includes(searchQuery.value.trim())) {
      recentSearches.value.unshift(searchQuery.value.trim());
      if (recentSearches.value.length > 5) {
        recentSearches.value.pop();
      }
      saveRecentSearches();
    }
  }, 300);
};

// Clear search
const clearSearch = () => {
  searchQuery.value = '';
  emit('clear');
  activeIndex.value = -1;
};

// Select an item from search results
const selectItem = (item) => {
  emit('select', item);
  dropdownVisible.value = false;
  
  // Update search query with selected item
  if (item.type === 'meridian') {
    searchQuery.value = item.name;
  } else {
    searchQuery.value = `${item.name} (${item.no})`;
  }
};

// Apply a recent search
const applyRecentSearch = (term) => {
  searchQuery.value = term;
  onSearch();
  showRecentSearches.value = false;
};

// Remove a recent search
const removeRecentSearch = (index, event) => {
  event.stopPropagation();
  recentSearches.value.splice(index, 1);
  saveRecentSearches();
};

// Clear all recent searches
const clearAllRecentSearches = () => {
  recentSearches.value = [];
  saveRecentSearches();
  showRecentSearches.value = false;
};

// Get all searchable items
const getAllSearchableItems = () => {
  const meridians = props.searchResults.meridians || [];
  const acupoints = props.searchResults.acupoints || [];
  return [...meridians, ...acupoints];
};

// Navigate through search results with keyboard
const navigateResults = (direction) => {
  const items = getAllSearchableItems();
  
  if (items.length === 0) return;
  
  if (direction === 'down') {
    activeIndex.value = activeIndex.value < items.length - 1 ? activeIndex.value + 1 : 0;
  } else if (direction === 'up') {
    activeIndex.value = activeIndex.value > 0 ? activeIndex.value - 1 : items.length - 1;
  }
  
  // Scroll to active item
  nextTick(() => {
    const activeElement = searchResultsRef.value?.querySelector('.result-item.active');
    if (activeElement && searchResultsRef.value) {
      const containerRect = searchResultsRef.value.getBoundingClientRect();
      const activeRect = activeElement.getBoundingClientRect();
      
      if (activeRect.bottom > containerRect.bottom) {
        searchResultsRef.value.scrollTop += activeRect.bottom - containerRect.bottom;
      } else if (activeRect.top < containerRect.top) {
        searchResultsRef.value.scrollTop -= containerRect.top - activeRect.top;
      }
    }
  });
};

// Keyboard navigation
const handleKeydown = (event) => {
  // If dropdown is not visible, don't handle keyboard navigation except Enter key
  if (!dropdownVisible.value && !showRecentSearches.value) {
    if (event.key === 'Enter') {
      onSearch();
    }
    return;
  }
  
  switch (event.key) {
    case 'ArrowDown':
      event.preventDefault();
      navigateResults('down');
      break;
    case 'ArrowUp':
      event.preventDefault();
      navigateResults('up');
      break;
    case 'Enter':
      event.preventDefault();
      if (activeIndex.value >= 0) {
        const items = getAllSearchableItems();
        if (items[activeIndex.value]) {
          selectItem(items[activeIndex.value]);
        }
      } else {
        onSearch();
      }
      break;
    case 'Escape':
      event.preventDefault();
      dropdownVisible.value = false;
      showRecentSearches.value = false;
      break;
  }
};

// Check if a meridian item is active
const isMeridianActive = (index) => {
  if (activeIndex.value === -1) return false;
  
  return index === activeIndex.value;
};

// Check if an acupoint item is active
const isAcupointActive = (index) => {
  if (activeIndex.value === -1) return false;
  
  const meridianCount = props.searchResults.meridians?.length || 0;
  return meridianCount + index === activeIndex.value;
};

// Handle input focus
const handleFocus = () => {
  isInputFocused.value = true;
  
  // Show recent searches if there's no query
  if (!searchQuery.value && recentSearches.value.length > 0) {
    showRecentSearches.value = true;
    dropdownVisible.value = false;
  } else if (props.searchResults.meridians.length > 0 || props.searchResults.acupoints.length > 0) {
    dropdownVisible.value = true;
  }
};

// Handle input blur
const handleBlur = () => {
  isInputFocused.value = false;
  
  // Don't hide dropdown immediately to allow for clicks on dropdown items
  setTimeout(() => {
    // Only hide if not clicked within dropdown
    if (!isMouseOverDropdown) {
      dropdownVisible.value = false;
      showRecentSearches.value = false;
    }
  }, 200);
};

// Track mouse over dropdown
let isMouseOverDropdown = false;

const handleMouseEnterDropdown = () => {
  isMouseOverDropdown = true;
};

const handleMouseLeaveDropdown = () => {
  isMouseOverDropdown = false;
};

// Keyboard shortcut (Ctrl+K) to focus search
const handleGlobalKeydown = (event) => {
  if ((event.ctrlKey || event.metaKey) && event.key === 'k') {
    event.preventDefault();
    searchInputRef.value?.focus();
  }
};

// Watch for changes in search results
watch(() => props.showResults, (newVal) => {
  dropdownVisible.value = newVal;
  
  if (newVal) {
    // Reset active index when showing dropdown
    activeIndex.value = -1;
    showRecentSearches.value = false;
  }
});

// Watch for changes in search query
watch(searchQuery, (newVal) => {
  if (!newVal) {
    emit('clear');
    
    if (isInputFocused.value && recentSearches.value.length > 0) {
      showRecentSearches.value = true;
      dropdownVisible.value = false;
    }
  } else {
    showRecentSearches.value = false;
  }
});

// Lifecycle hooks
onMounted(() => {
  loadRecentSearches();
  document.addEventListener('keydown', handleGlobalKeydown);
});

onBeforeUnmount(() => {
  document.removeEventListener('keydown', handleGlobalKeydown);
});
</script>

<template>
  <div class="search-bar-container">
    <div class="search-input-wrapper">
      <ElInput
        ref="searchInputRef"
        v-model="searchQuery"
        class="search-input"
        placeholder="搜索经络或穴位... (Ctrl+K)"
        clearable
        @input="onSearch"
        @keydown="handleKeydown"
        @focus="handleFocus"
        @blur="handleBlur"
        @clear="clearSearch"
      >
        <template #prefix>
          <el-icon class="search-icon"><i class="el-icon-search"></i></el-icon>
        </template>
        <template #append>
          <ElButton
            type="primary"
            @click="onSearch"
          >
            搜索
          </ElButton>
        </template>
      </ElInput>
    </div>
    
    <!-- Recent searches -->
    <div
      v-if="showRecentSearches && recentSearches.length > 0"
      ref="searchResultsRef"
      class="search-results-dropdown recent-searches"
      @mouseenter="handleMouseEnterDropdown"
      @mouseleave="handleMouseLeaveDropdown"
    >
      <div class="result-section">
        <div class="result-section-title">
          <span>最近搜索</span>
          <ElButton
            type="text"
            size="small"
            @click="clearAllRecentSearches"
          >
            清除历史
          </ElButton>
        </div>
        <ElScrollbar height="200px">
          <div class="result-items">
            <div
              v-for="(term, index) in recentSearches"
              :key="index"
              class="result-item recent-item"
              @click="applyRecentSearch(term)"
            >
              <i class="el-icon-time"></i>
              <div class="item-name">{{ term }}</div>
              <ElButton
                type="text"
                size="small"
                class="delete-button"
                @click="removeRecentSearch(index, $event)"
              >
                <i class="el-icon-delete"></i>
              </ElButton>
            </div>
          </div>
        </ElScrollbar>
      </div>
    </div>
    
    <!-- Search results -->
    <div
      v-if="dropdownVisible"
      ref="searchResultsRef"
      class="search-results-dropdown"
      @mouseenter="handleMouseEnterDropdown"
      @mouseleave="handleMouseLeaveDropdown"
    >
      <div v-if="searchResults.meridians.length === 0 && searchResults.acupoints.length === 0" class="no-results">
        <i class="el-icon-no-data"></i>
        <div class="no-results-text">
          <div>无搜索结果</div>
          <small>请尝试其他关键词</small>
        </div>
      </div>
      
      <ElScrollbar v-else height="400px">
        <div v-if="searchResults.meridians.length > 0" class="result-section">
          <div class="result-section-title">
            <span>经络</span>
            <ElBadge :value="searchResults.meridians.length" type="primary" />
          </div>
          <div class="result-items">
            <div
              v-for="(meridian, index) in searchResults.meridians"
              :key="`meridian-${meridian.id}`"
              :class="['result-item', 'meridian-item', { active: isMeridianActive(index) }]"
              @click="selectItem(meridian)"
              @mouseenter="activeIndex = index"
            >
              <div class="item-icon meridian-icon">{{ meridian.no }}</div>
              <div class="item-content">
                <div class="item-name">{{ meridian.name }}</div>
                <div class="item-meta">编号: {{ meridian.no }}</div>
              </div>
            </div>
          </div>
        </div>
        
        <div v-if="searchResults.acupoints.length > 0" class="result-section">
          <div class="result-section-title">
            <span>穴位</span>
            <ElBadge :value="searchResults.acupoints.length" type="success" />
          </div>
          <div class="result-items">
            <div
              v-for="(acupoint, index) in searchResults.acupoints"
              :key="`acupoint-${acupoint.id}`"
              :class="['result-item', 'acupoint-item', { active: isAcupointActive(index) }]"
              @click="selectItem(acupoint)"
              @mouseenter="activeIndex = props.searchResults.meridians.length + index"
            >
              <div class="item-icon acupoint-icon">{{ acupoint.no }}</div>
              <div class="item-content">
                <div class="item-name">{{ acupoint.name }}</div>
                <div class="item-meta">
                  <ElTag size="small" type="info">{{ acupoint.meridian_name }}</ElTag>
                  <span class="acupoint-code">{{ acupoint.no }}</span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </ElScrollbar>
    </div>
  </div>
</template>

<style scoped>
.search-bar-container {
  position: relative;
  width: 100%;
  max-width: 500px;
}

.search-input-wrapper {
  position: relative;
  width: 100%;
}

.search-input {
  width: 100%;
}

.search-icon {
  color: #909399;
}

.search-results-dropdown {
  position: absolute;
  top: calc(100% + 5px);
  left: 0;
  width: 100%;
  background-color: white;
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  margin-top: 5px;
  z-index: 9999;
  max-height: 450px;
  border: 1px solid #ebeef5;
}

.no-results {
  padding: 30px 20px;
  text-align: center;
  color: #909399;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 15px;
}

.no-results i {
  font-size: 36px;
  opacity: 0.5;
}

.no-results-text {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.no-results small {
  font-size: 12px;
  color: #c0c4cc;
}

.result-section {
  border-bottom: 1px solid #ebeef5;
}

.result-section:last-child {
  border-bottom: none;
}

.result-section-title {
  padding: 10px 15px;
  font-size: 13px;
  font-weight: 600;
  color: #606266;
  background-color: #f5f7fa;
  display: flex;
  justify-content: space-between;
  align-items: center;
  position: sticky;
  top: 0;
  z-index: 1;
}

.result-items {
  overflow-y: auto;
}

.result-item {
  padding: 12px 15px;
  display: flex;
  align-items: center;
  cursor: pointer;
  transition: background-color 0.2s, border-color 0.2s;
  border-left: 3px solid transparent;
}

.result-item:hover {
  background-color: #f5f7fa;
}

.result-item.active {
  background-color: #ecf5ff;
  border-left-color: #409eff;
}

.item-icon {
  width: 36px;
  height: 36px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 12px;
  font-weight: bold;
  flex-shrink: 0;
}

.meridian-icon {
  background-color: #ecf5ff;
  color: #409eff;
  font-weight: bold;
}

.acupoint-icon {
  background-color: #f0f9eb;
  color: #67c23a;
  font-size: 12px;
}

.item-content {
  flex: 1;
  min-width: 0;
}

.item-name {
  font-size: 14px;
  color: #303133;
  margin-bottom: 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.item-meta {
  font-size: 12px;
  color: #909399;
  display: flex;
  align-items: center;
  gap: 8px;
}

.acupoint-code {
  color: #909399;
}

.recent-item {
  padding: 10px 15px;
}

.recent-item i {
  margin-right: 10px;
  color: #909399;
}

.delete-button {
  opacity: 0;
  transition: opacity 0.2s;
}

.result-item:hover .delete-button {
  opacity: 1;
}

/* Icon styles */
.el-icon-search:before {
  content: "🔍";
}

.el-icon-time:before {
  content: "🕒";
}

.el-icon-delete:before {
  content: "🗑️";
}

.el-icon-no-data:before {
  content: "📭";
}

@media (max-width: 768px) {
  .search-bar-container {
    width: 100%;
  }
}
</style>